/*
 *	misc.c
 *
 *	Created on: 2017年5月19日
 *	Author: NKJ
 */

#include "misc.h"
#include "gatt_db.h"
#include "native_gecko.h"
#include "bg_types.h"
#include "stdio.h"

const atcmd atcmdass[]={
    {ATCMD_NONE,                "",                         "ERROR\r\n"},
    {ATCMD_HEADER,              "AT+",                      ""},
    {ATCMD_END,                 "\r\n",                     ""},
    {ATCMD_PLUS,                "AT+\r\n",                  "OK\r\n"},
    {ATCMD_DFU,                 "AT+DFU=\r\n",              "DFU=\r\n"},
    {ATCMD_QUERY_MAC,           "AT+MAC?\r\n",              "MAC:"},
    {ATCMD_QUERY_BLEWORKSTYLE,  "AT+BLEWORKSTYLE?\r\n",     "BLEWORKSTYLE="},
    {ATCMD_SET_BLEWORKSTYLE,    "AT+BLEWORKSTYLE=\r\n",     "BLEWORKSTYLE="},
    {ATCMD_QUERY_VERSION,       "AT+VERSION?\r\n",          VERSION},
    {ATCMD_SCANSTART,           "AT+SCANSTART?\r\n",        "SCANSTART\r\n"},
    {ATCMD_SCANSTOP,            "AT+SCANSTOP?\r\n",         "SCANSTOP\r\n"},
    {ATCMD_SET_DATAFILTER,      "AT+DATAFILTER=\r\n",       "DATAFILTER="},
    {ATCMD_GOTO_SLEEP,          "AT+SLEEP?\r\n",            "SLEEPOK\r\n"},
    {ATCMD_SET_NAME,            "AT+NAME=\r\n",             "NAME="},
    {ATCMD_QUREY_CONSTA,        "AT+CONSTA?\r\n",           "CONSTA="},
    {ATCMD_SET_HR,              "AT+HR=\r\n"                ,"HR="},
    {ATCMD_SET_BATLEVEL,        "AT+BATLEVEL=\r\n",         "BATLEVEL="},
    {ATCMD_SET_BATVOLTAGE,      "AT+BATVOLTAGE=\r\n",       "BATVOLTAGE="},
    {ATCMD_SET_PIN,             "AT+PIN=\r\n"               ,"PIN="},
    {ATCMD_DISCON,              "AT+DISCON=\r\n"            ,"DISCON="},
    {ATCMD_QUERY_ALL,           "AT+ALL?\r\n"               ,"ALL:\r\n"},
    {ATCMD_SHUTDOWN,            "AT+SHUTDOWN?\r\n"          ,"SHUTDOWN\r\n"},
    {ATCMD_CONNECT,             "AT+CONNECT=\r\n"           ,"CONNECT="},

    {ATCMD_ERROR,               "",                         "ERROR\r\n"},
};

extern uint8_t appsta;

/* 获得AT命令
 * 函数名：enum _at_cmd_id getATCMD(char *atcmd,uint8_t len)
 * 输入：atcmd  命令指针 ,len 输入长度到 \r或\n为止
 * 返回：命令ID
*/
enum _at_cmd_id getATCMD(char *atcmd,uint8_t len)
{
	uint8_t i = 0;
	for(i = 0; atcmdass[i].id != ATCMD_ERROR; i ++)
	{
		if((len == (strlen(atcmdass[i].atcmdstr) - 2)) && cmpi2Array((uint8_t *)atcmd,(uint8_t *)atcmdass[i].atcmdstr,len))
		{
			break;
		}
	}

	if(cmpi2Array((uint8_t *)atcmd,(uint8_t *)atcmdass[ATCMD_DFU].atcmdstr,strlen(atcmdass[ATCMD_DFU].atcmdstr) - 2))
		i = ATCMD_DFU;
    else if(cmpi2Array((uint8_t *)atcmd,(uint8_t *)atcmdass[ATCMD_SET_BLEWORKSTYLE].atcmdstr,strlen(atcmdass[ATCMD_SET_BLEWORKSTYLE].atcmdstr) - 2))
		i = ATCMD_SET_BLEWORKSTYLE;
	else if(cmpi2Array((uint8_t *)atcmd,(uint8_t *)atcmdass[ATCMD_SET_DATAFILTER].atcmdstr,strlen(atcmdass[ATCMD_SET_DATAFILTER].atcmdstr) - 2))
		i = ATCMD_SET_DATAFILTER;
	else if(cmpi2Array((uint8_t *)atcmd,(uint8_t *)atcmdass[ATCMD_SET_NAME].atcmdstr,strlen(atcmdass[ATCMD_SET_NAME].atcmdstr) - 2))
		i = ATCMD_SET_NAME;
	else if(cmpi2Array((uint8_t *)atcmd,(uint8_t *)atcmdass[ATCMD_SET_HR].atcmdstr,strlen(atcmdass[ATCMD_SET_HR].atcmdstr) - 2))
		i = ATCMD_SET_HR;
    else if(cmpi2Array((uint8_t *)atcmd,(uint8_t *)atcmdass[ATCMD_SET_BATLEVEL].atcmdstr,strlen(atcmdass[ATCMD_SET_BATLEVEL].atcmdstr) - 2))
		i = ATCMD_SET_BATLEVEL;
    else if(cmpi2Array((uint8_t *)atcmd,(uint8_t *)atcmdass[ATCMD_SET_BATVOLTAGE].atcmdstr,strlen(atcmdass[ATCMD_SET_BATVOLTAGE].atcmdstr) - 2))
		i = ATCMD_SET_BATVOLTAGE;
	else if(cmpi2Array((uint8_t *)atcmd,(uint8_t *)atcmdass[ATCMD_SET_PIN].atcmdstr,strlen(atcmdass[ATCMD_SET_PIN].atcmdstr) - 2))
		i = ATCMD_SET_PIN;
	else if(cmpi2Array((uint8_t *)atcmd,(uint8_t *)atcmdass[ATCMD_DISCON].atcmdstr,strlen(atcmdass[ATCMD_DISCON].atcmdstr) - 2))
		i = ATCMD_DISCON;
	else if(cmpi2Array((uint8_t *)atcmd,(uint8_t *)atcmdass[ATCMD_CONNECT].atcmdstr,strlen(atcmdass[ATCMD_CONNECT].atcmdstr) - 2))
		i = ATCMD_CONNECT;

    if(atcmdass[i].id == ATCMD_HEADER)
    {
        i = ATCMD_PLUS;
    }
    if((appsta != START) && (atcmdass[i].id != ATCMD_PLUS) && (atcmdass[i].id != ATCMD_DFU))
        i = ATCMD_ERROR;

    return (atcmdass[i].id);
}

/* 设置发送功率
 * 函数名：uint8_t txpSetTransmitPower(int16_t txpTransmitPowerToSet)
 * 输入： 发送功率 * 10
 * 返回：设置成功后的功率值
 */
uint8_t txpSetTransmitPower(int16_t txpTransmitPowerToSet)
{
    struct gecko_msg_system_set_tx_power_rsp_t* txpPowerResponse;
    uint8_t txpTransmitPowerTemp;

    gecko_cmd_system_halt(1);
    txpPowerResponse = gecko_cmd_system_set_tx_power(txpTransmitPowerToSet);
    /* Save value which was set. This may differ from desired value */
    /* Save value to GATT Database */
    /* Divide by 10 as txpTransmitPower is in dBm * 10, but the characteristic is in dBm */
    txpTransmitPowerTemp = (uint8_t)(txpPowerResponse->set_power / 10);
    gecko_cmd_gatt_server_write_attribute_value(gattdb_tx_power, 0, 1, (uint8_t * )&txpTransmitPowerTemp);
    gecko_cmd_system_halt(0);

    return (txpTransmitPowerTemp * 10);
}

/* 10进制字符串转10进制数
 * 函数名：int matoi(char* pstr)
 * 输入：字符串
 * 返回：10进制数
 */
int matoi(char* pstr)
{
    int Ret_Integer = 0;
    int Integer_sign = 1;
    /*
     * 判断指针是否为空
     */
    if(pstr == NULL)
    {
        return 0;
    }
    /*
     * 跳过前面的空格字符
     */
    while(*pstr == ' ')
    {
        pstr++;
    }
    /*
     * 判断正负号
     * 如果是正号，指针指向下一个字符
     * 如果是符号，把符号标记为Integer_sign置-1，然后再把指针指向下一个字符
     */
    if(*pstr == '-')
    {
        Integer_sign = -1;
    }
    if(*pstr == '-' || *pstr == '+')
    {
        pstr++;
    }
    /*
     * 把数字字符串逐个转换成整数，并把最后转换好的整数赋给Ret_Integer
     */
    while(*pstr >= '0' && *pstr <= '9')
    {
        Ret_Integer = Ret_Integer * 10 + *pstr - '0';
        pstr++;
    }
    Ret_Integer = Integer_sign * Ret_Integer;

    return Ret_Integer;
}

/* 进制转换
 * 函数名：uint32_t mint(char *data)
 * 输入：字符串，0x开头为16进制字符串，其它认为是10进制字符串
 * 返回：10进制数
 */
uint32_t mint(char *data)
{
    uint32_t i = 0,j = 0;
    if(data[1] == 'X' || data[1] == 'x')
    {
        data += 2;
        while(*data)
        {
            if(*data <= '9')
                j = *data - '0';
            else if(*data <= 'F')
                j = *data - 'A' + 10;
            else if(*data <= 'f')
                j = *data - 'a' + 10;

            i = i * 16 + j;
            data ++;
        }
    }
    else
    {
        return matoi(data);
    }
    return i;
}

/* 进制转换
 * 函数名：uint32_t mintl(char *data,uint16_t start,uint16_t end,uint8_t he)
 * 输入：字符串，起始索引，终止索引，字符串进制
 * 返回：10进制数
 */
uint32_t mintl(char *data,uint16_t start,uint16_t end,uint8_t hex)
{
    char buf[12] = {0,'X',0,0,0,0,0,0,0,0,0,0};
    uint32_t i = 0;
    if((end - start) > 8)
        return 0;
    for(i = 0;i < (end - start);i ++)
    {
        if(hex == 16)
            buf[2 + i] = data[start + i];
        else if(hex == 10)
            buf[i] = data[start + i];
    }
    return mint(buf);
}

/* 将字符串转化为地址数组
 * 函数名：uint8_t str2bdaddr(char str[],uint8_t bd[])
 * 输入：字符串物理地址 00:0B:57:05:AE:3F，物理地址{3F,AE,05,57,0B,00}
 * 返回：0
 */
uint8_t str2bdaddr(char str[],uint8_t bd[])
{
    char buf[5] = {0};
    for(uint8_t i = 0;i < 6;i ++)
    {
        buf[0] = '0';
        buf[1] = 'x';
        buf[2] = str[i * 3 + 0];
        buf[3] = str[i * 3 + 1];
        buf[4] = '\0';
        bd[5 - i] =  mint(buf);
    }
    return 0;
}

/* 拷贝两个数组 (len < 0xff)
 * 函数名：uint8_t cpy2Array(uint8_t array1[],uint8_t array2[],uint8_t len)
 * 输入：array1  目标数组1指针
 * 		array2  源数组2指针
 * 		len     拷贝长度
 * 返回：
 */
void cpy2Array(uint8_t array1[],uint8_t array2[],uint8_t len)
{
    for(uint8_t i = 0;i < len;i ++)
    {
        array1[i] = array2[i];
    }
}

/* 小写转大写
 * 函数名：uint8_t letterUpper(uint8_t letter)
 * 输入：转换对象
 * 返回：转换后值
 */
static uint8_t letterUpper(uint8_t letter)
{
    if('a' <= letter && letter <= 'z')
        letter -= 32;
    return letter;
}

/* 比较两个数组 (len < 0xff)
 * 函数名：uint8_t cmp2Array(uint8_t array1[],uint8_t array2[],uint8_t len)
 * 输入：array1  数组1指针
 * 		array2  数组2指针
 * 		len     比较长度
 * 返回：一致返回1 不一致返回0
 */
uint8_t cmp2Array(uint8_t array1[],uint8_t array2[],uint8_t len)
{
    for(uint8_t i = 0;i < len;i ++)
    {
        if(array1[i] != array2[i])
            return 0;
    }
    return 1;
}

/* 比较两个数组 ,字母不区分大小写(len < 0xff)
 * 函数名：uint8_t cmpi2Array(uint8_t array1[],uint8_t array2[],uint8_t len)
 * 输入：array1  数组1指针
 * 		array2  数组2指针
 * 		len     比较长度
 * 返回：一致返回1 不一致返回0
 */
uint8_t cmpi2Array(uint8_t array1[],uint8_t array2[],uint8_t len)
{
    for(uint8_t i = 0;i < len;i ++)
    {
        if(letterUpper(array1[i]) != letterUpper(array2[i]))
            return 0;
    }
    return 1;
}





